package com.example.dingtalkwebproject.controller;

import com.example.dingtalkwebproject.exception.BusinessException;
import com.example.dingtalkwebproject.pojo.*;
import com.example.dingtalkwebproject.pojo.vo.rejectReportedVO;
import com.example.dingtalkwebproject.pojo.vo.wBlShipHdVO;
import com.example.dingtalkwebproject.service.*;
import com.example.dingtalkwebproject.utils.AjaxResult;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/upload")
public class uploadVideoController {

    private static final String UPLOAD_DIR = "/data/sharefile/B_BL_BLOCK_STORE_VIDEO/";
//    private static final String UPLOAD_DIR = "D:/path/to/your/upload/directory/";

    @Autowired
    private VideoStorageService videoStorageService;
    @Autowired
    private wBlShipHdService wBlShipHdService;
    @Autowired
    private wBlShipDtService wBlShipDtService;
    @Autowired
    private CWeiXinConfigQyService cWeiXinConfigQyService;
    @Autowired
    private dArcStaffService dArcStaffService;
    @Autowired
    private dingTalkMessageQueueService dingTalkMessageQueueService;
    @Autowired
    private dingTalkSendContentService dingTalkSendContentService;
    @Autowired
    private sysLoginUserService sysLoginUserService;

    private static final String defectiveJpg = "https://newerp.mumuso.com/uploadfile/W_BL_SHIP_HD_VIDEO/wlcc.JPG";

    private static final String noticeDingTalkChatId = "CHAT01B7A8792EF82AB271E1B23EFC8ACAC5";
    private static final String operateDingTalkChatId = "CHATE078CD83A9BEEAA8B6E37E5D719436D6";


    // 报废视频上传
    @PostMapping("/uploadScrap")
    public AjaxResult uploadScrapVideo(@RequestPart("rejectReportedVO") rejectReportedVO rejectReportedVO, @RequestPart("file") MultipartFile file) {
        validateRequestScrap(rejectReportedVO, file);


        // 判断当前状态 如果是004
        if ("004".equals(rejectReportedVO.getStatus())) {
            return AjaxResult.error("当前物流残次单【" + rejectReportedVO.getBillId() + "】已经被风控审核，当前单据已经结束，不可再上传报废视频!");
        }

        // 将报废视频上传
        String scrapFileName = storeVideoFile(file);
        rejectReportedVO.setScrapVideoUrl(scrapFileName);

        // 然后开始进行更新视频的操作
        int updated = wBlShipHdService.updateScrapVideoByBillId(rejectReportedVO);
        if (updated > 0) {
            // 如果门店已经上传报废视频 通知门控部门
            // 提醒张元元
            List<dArcStaff> staffs = getRecipientRiskStaffs(rejectReportedVO, "通知张元元");
            CWeiXinConfigQy robotConfig = getCobotConfig();
            CWeiXinConfigQy operateRobotConfig = getCobotOperateConfig();
            staffs.forEach(staff -> {
                dingTalkMessageQueue queue = buildMessageQueueCg(rejectReportedVO, robotConfig, staff, operateRobotConfig);
                sendDingTalkMessage(queue);
            });

            // 获取所有物流人员
            List<sysLoginUser> users = sysLoginUserService.selectAllLogisticsInfos();
            // 将钉钉工号使用逗号隔开
            // 使用Stream API处理
            String staffIds = users.stream()                       // 创建流
                    .map(sysLoginUser::getOldStaffId)                // 提取oldStaffId
                    .filter(id -> id != null && !id.isEmpty())        // 过滤掉null和空字符串
                    .collect(Collectors.joining(","));
            // 通知物流
            if (StringUtils.isNotBlank(staffIds)) {
                sendAlreadyUploadToCg(rejectReportedVO, robotConfig, staffIds);
            }
            return AjaxResult.success("物流报废视频已经上传完成，请勿重复提交!");
        } else {
            return AjaxResult.error("上传失败!");
        }
    }


    private void sendAlreadyUploadToCg(rejectReportedVO wBlShipHdVO, CWeiXinConfigQy operateRobot, String staffIds) {
        // 根据人员获取采购人员信息
        // 3. 消息链接（跳转至带视频的详情页）
        String messageUrl = String.format("https://mms.mumuso.com:8214/index/#/risk/?billId=%s&staffId=%s",
                wBlShipHdVO.getBillId(), wBlShipHdVO.getCgStaff());
        // 4. 核心消息内容构建
        StringBuilder markdownBuilder = new StringBuilder()
                .append("### ✅ 残次物流商品处理进度更新(物流残次提报)\n\n")
                .append("#### **当前状态**\n")
                .append("- 🛒 **门店名称:** ").append(wBlShipHdVO.getStoreName()).append("\n")
                .append("- 👤 **提报人:** ").append(wBlShipHdVO.getStaffName()).append("\n\n")
                .append("- 📦 **商品名称:** ").append(wBlShipHdVO.getItemName()).append("\n")
                .append("- 🎥 **报废视频:** ").append(wBlShipHdVO.getScrapVideoUrl() != null ? "已上传" : "待补传").append("\n\n")
                .append("---\n")
                .append("#### **处理流程**\n")
                .append("1. 物流审核: 已完成 (").append("根据你的处理决定：直接报废，门店已上传报废视频").append(")\n")
                .append("2. 门店操作: ").append(wBlShipHdVO.getScrapVideoUrl() != null ? "视频已上传" : "需补传视频").append("\n\n")
                .append("🔗 **查看详情:** [点击查看完整记录](").append(messageUrl).append(")\n\n")
                .append("> 📌 视频存档编号: ").append(wBlShipHdVO.getBillId());

        // 发送给采购人员
        // 创建消息队列对象
        dingTalkMessageQueue queue = new dingTalkMessageQueue();
        queue.setMsgType("MARKDOWN");
        queue.setTitle("️✅ 残次物流商品处理进度更新(物流残次提报)");  // 标题也加上警告图标
        queue.setRobotToken(operateRobot.getAccessToken());
        queue.setRobotCode(operateRobot.getAeskey());
        queue.setMarkdownContent(markdownBuilder.toString());
        queue.setUserIds(staffIds);   // 指定接收人

        // 发送消息
        sendDingTalkMarkdownMessage(queue);
    }

    private void sendDingTalkMarkdownMessage(dingTalkMessageQueue queue) {
        int result = dingTalkMessageQueueService.sendDingTalkMarkdownMessage(queue);
        if (result <= 0) throw new BusinessException("消息发送失败");
    }

    private void sendDingTalkMessage(rejectReportedVO wBlShipHdVO) {
        // 1. 基础配置获取
        CWeiXinConfigQy cobotConfig = getCobotOperateConfig();
        dArcStaff dArcStaff = dArcStaffService.selectDingUserIdByStaffId("MS02901");

        // 2. 构建消息标题（突出审核完成状态）
        String title = String.format("%s-物流残次处理完成（视频已上传）", wBlShipHdVO.getStoreId());

        // 3. 消息链接（跳转至带视频的详情页）
        String messageUrl = String.format("https://mms.mumuso.com:8214/index/#/risk/?billId=%s&staffId=%s&type=%s",
                wBlShipHdVO.getBillId(), "MS02901", "endvideo");

        // 4. 核心消息内容构建
        StringBuilder markdownBuilder = new StringBuilder()
                .append("### ✅ 残次商品处理进度更新\n\n")
                .append("#### **当前状态**\n")
                .append("- 🛒 **门店名称:** ").append(wBlShipHdVO.getStoreName()).append("\n")
                .append("- 👤 **提报人:** ").append(wBlShipHdVO.getStaffName()).append("\n\n")
                .append("- 📦 **商品名称:** ").append(wBlShipHdVO.getItemName()).append("\n")
                .append("- 🎥 **报废视频:** ").append(wBlShipHdVO.getScrapVideoUrl() != null ? "已上传" : "待补传").append("\n\n")
                .append("---\n")
                .append("#### **处理流程**\n")
                .append("1. 物流审核: 已完成 (").append("根据你的处理决定：直接报废，门店已上传报废视频").append(")\n")
                .append("2. 门店操作: ").append(wBlShipHdVO.getScrapVideoUrl() != null ? "报废视频已上传" : "需补传报废视频").append("\n\n")
                .append("🔗 **查看详情:** [点击查看完整记录](").append(messageUrl).append(")\n\n")
                .append("> 📌 视频存档编号: ").append(wBlShipHdVO.getBillId());

        // 5. 发送给门店的链接消息
        dingTalkMessageQueue queue = new dingTalkMessageQueue();
        queue.setMsgType("LINK");
        queue.setTitle(title);
        queue.setText(" 物流审核已完成，门店已上传报废视频！");
        queue.setRobotCode(cobotConfig.getAeskey());
        queue.setRobotToken(cobotConfig.getAccessToken());
        queue.setMessageUrl(messageUrl);
        queue.setPicUrl(defectiveJpg);  // 可替换为视频封面图
        if (StringUtils.isNotBlank(dArcStaff.getOldStaffId())) {
            queue.setUserIds(dArcStaff.getOldStaffId());
        }
        sendDingTalkMessage(queue);

        // 发送给采购人员
        dingTalkSendContent textContent = new dingTalkSendContent();
        textContent.setChatId(noticeDingTalkChatId);
        textContent.setTextContent("🚨 残次商品提报通知");
        int inserted = dingTalkSendContentService.insertTextContent(textContent);
        // 6. 发送给采购的Markdown通知
        if (inserted > 0) {
            dingTalkSendContent content = new dingTalkSendContent();
            content.setMarkdownContent(markdownBuilder.toString());
            content.setChatId(noticeDingTalkChatId);
            dingTalkSendContentService.insertMarkdownMessage(content);
        }
    }


    private dingTalkMessageQueue buildMessageQueueCg(rejectReportedVO vo,
                                                     CWeiXinConfigQy config, dArcStaff staff, CWeiXinConfigQy operateRobotConfig) {
        StringBuilder title = new StringBuilder()
                .append(vo.getStoreId()).append("-").append("提报的物流残次").append("--").append(vo.getItemName());

        // 构建带参数的URL
        String messageUrl = new StringBuilder("https://mms.mumuso.com:8214/index/#/risk/?")
                .append("billId=").append(vo.getBillId())
                .append("&staffId=").append("MS02901").append("&type=").append("endvideo")
                .toString();

        StringBuilder sb = new StringBuilder().append(vo.getRemark()).append("——").append("物流已审核,门店已上传报废视频,请风控点击链接进行审核操作!");

        // 直接创建对象并设置属性
        dingTalkMessageQueue queue = new dingTalkMessageQueue();
        queue.setMsgType("LINK");
        queue.setTitle(title.toString());
        queue.setText(sb.toString());
        if ("operate".equals(staff.getSendType())) {
            queue.setRobotToken(operateRobotConfig.getAccessToken());
            queue.setRobotCode(operateRobotConfig.getAeskey());
        } else {
            queue.setRobotToken(config.getAccessToken());
            queue.setRobotCode(config.getAeskey());
        }
        queue.setMessageUrl(messageUrl);
        queue.setPicUrl(defectiveJpg);
        queue.setUserIds(staff.getOldStaffId());

        return queue;
    }

    private List<dArcStaff> getRecipientRiskStaffs(rejectReportedVO vo, String type) {
        List<dArcStaff> staffs = new ArrayList<>();
        if (type.equals("通知张元元")) {
            addStaffIfValid(staffs, "MS02901", dArcStaffService::selectDingUserIdByStaffId, "operate");
        } else {
            addStaffIfValid(staffs, vo.getCgStaff(), dArcStaffService::selectDingUserIdByStaffId, "notice");
        }
        return staffs;
    }

    @PostMapping("/uploadVideo")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult uploadVideo(
            @RequestPart("wBlShipHdVO") wBlShipHdVO wBlShipHdVO,
            @RequestPart("file") MultipartFile file) {

        // 1. 参数校验
        validateRequest(wBlShipHdVO, file);

        // 2. 存储视频文件
        String storedFilename = storeVideoFile(file);

        // 3. 构建并保存主表信息
        wBlShipHd hd = buildHeaderEntity(wBlShipHdVO, storedFilename);
        int insertedHd = saveHeaderInfo(hd);
        if (insertedHd <= 0) {
            return AjaxResult.error("物流残次报废提交失败!");
        }

        // 4. 构建并保存明细信息
        wBlShipDt dt = buildDetailEntity(wBlShipHdVO);
        int insertedDt = saveDetailInfo(dt);
        if (insertedDt <= 0) {
            return AjaxResult.error("物流残次报废商品明细信息提交失败!");
        }
        // 发送钉钉通知
        // 如果是区域经理 那么就发送操作信息
        // 如果是采购员 那么就发送通知信息
        sendDingTalkNotifications(wBlShipHdVO, hd);
        return AjaxResult.success(" 你已经完成当前商品【" + wBlShipHdVO.getItemName() + "】的物流残次提报!");
    }

    private void validateRequest(wBlShipHdVO vo, MultipartFile file) {
        if (ObjectUtils.isEmpty(vo)) {
            throw new BusinessException("请求参数不能为空");
        }
        if (file.isEmpty()) {
            throw new BusinessException("视频文件不能为空");
        }
    }

    private void validateRequestScrap(rejectReportedVO vo, MultipartFile file) {
        if (ObjectUtils.isEmpty(vo)) {
            throw new BusinessException("请求参数不能为空");
        }
        if (file.isEmpty()) {
            throw new BusinessException("视频文件不能为空");
        }
    }


    private String storeVideoFile(MultipartFile file) {
        try {
            return videoStorageService.storeVideo(file);
        } catch (IOException e) {
            throw new BusinessException("视频存储失败", e.getMessage());
        }
    }

    private wBlShipHd buildHeaderEntity(wBlShipHdVO vo, String filename) {
        wBlShipHd hd = new wBlShipHd();
        hd.setFj(StringUtils.isNotBlank(filename) ? filename : null);
        hd.setBillId(StringUtils.isNotBlank(vo.getBillId()) ? vo.getBillId() : null);
        hd.setRecStore(StringUtils.isNotBlank(vo.getStoreId()) ? vo.getStoreId() : null);
        hd.setGnwcc(StringUtils.isNotBlank(vo.getGnwcc()) ? vo.getGnwcc() : null);
        hd.setStaffId(getValidStaffId(vo));
        hd.setRstaffId(getValidStaffId(vo));
        hd.setBuType(StringUtils.isNotBlank(vo.getBuType()) ? vo.getBuType() : "004");
        hd.setCompanyId(StringUtils.isNotBlank(vo.getCompanyId()) ? vo.getCompanyId() : null);
        hd.setOaBillId(StringUtils.isNotBlank(vo.getOaBillId()) ? vo.getOaBillId() : null);
        hd.setRemark(StringUtils.isNotBlank(vo.getRemark()) ? vo.getRemark() : null);
        hd.setYdh(StringUtils.isNotBlank(vo.getYdh()) ? vo.getYdh() : null);
        hd.setXh(StringUtils.isNotBlank(vo.getXh()) ? vo.getXh() : null);
        return hd;
    }

    private String getValidStaffId(wBlShipHdVO vo) {
        return StringUtils.isNotBlank(vo.getStaffId())
                ? vo.getStaffId()
                : (StringUtils.isNotBlank(vo.getRStaffId()) ? vo.getRStaffId() : null);
    }

    private int saveHeaderInfo(wBlShipHd hd) {
        int inserted = wBlShipHdService.insertShipHdInfo(hd);
        if (inserted <= 0) throw new BusinessException("残次单表头保存失败");
        return inserted;
    }

    private wBlShipDt buildDetailEntity(wBlShipHdVO vo) {
        wBlShipDt dt = new wBlShipDt();
        dt.setBillId(StringUtils.isNotBlank(vo.getBillId()) ? vo.getBillId() : null);
        dt.setItemId(vo.getItemId());
        dt.setSellPrice(vo.getSellPrice());
        dt.setPosQty(-Math.abs(vo.getPosQty()));
        dt.setRemark(vo.getRemark());
        return dt;
    }

    private int saveDetailInfo(wBlShipDt dt) {
        int insertedDt = wBlShipDtService.insertShipDtInfo(dt);
        if (insertedDt <= 0) throw new BusinessException("残次单表体保存失败");
        return insertedDt;
    }

    private void sendDingTalkNotifications(wBlShipHdVO vo, wBlShipHd hd) {
        // 通知类机器人
        CWeiXinConfigQy robotConfig = getCobotConfig();
        // 获取操作类机器人配置信息
        CWeiXinConfigQy robotOperateConfig = getCobotOperateConfig();
        List<dArcStaff> recipients = getRecipientStaffs(vo);

        recipients.forEach(staff -> {
            buildMessageQueue(vo, hd, robotConfig, staff, robotOperateConfig);
        });
    }

    // 获取通知类机器人信息
    private CWeiXinConfigQy getCobotConfig() {
        CWeiXinConfigQy config = cWeiXinConfigQyService.selectRobotInfo();
        if (ObjectUtils.isEmpty(config)) throw new BusinessException("未获取到当前机器人配置信息");
        return config;
    }

    // 获取操作类机器人信息
    private CWeiXinConfigQy getCobotOperateConfig() {
        CWeiXinConfigQy config = cWeiXinConfigQyService.selectOperationRobotInfo();
        if (ObjectUtils.isEmpty(config)) throw new BusinessException("未获取到当前机器人配置信息");
        return config;
    }

    private List<dArcStaff> getRecipientStaffs(wBlShipHdVO vo) {
        List<dArcStaff> staffs = new ArrayList<>();
        // 先获取区域负责人
        dArcStaff areaStaff = vo.getAreaStaff() != null ?
                dArcStaffService.selectDingUserIdByStaffId(vo.getAreaStaff()) : null;

        // 获取提报人
        dArcStaff submitterStaff = vo.getStaffId() != null ?
                dArcStaffService.selectDingUserIdByStaffId(vo.getStaffId()) : null;

        // 添加区域负责人（操作类型）
        if (areaStaff != null) {
            areaStaff.setSendType("operate");
            staffs.add(areaStaff);
        }

        // 添加提报人（通知类型），但确保不是同一个人
        if (submitterStaff != null &&
            (areaStaff == null || !submitterStaff.getStaffId().equals(areaStaff.getStaffId()))) {
            submitterStaff.setSendType("notice");
            staffs.add(submitterStaff);
        }

        return staffs;
    }

    private void addStaffIfValid(List<dArcStaff> list, String staffId,
                                 Function<String, dArcStaff> selector,
                                 String sendType) {
        if (StringUtils.isNotBlank(staffId)) {
            dArcStaff staff = selector.apply(staffId);
            if (ObjectUtils.isNotEmpty(staff)) {
                staff.setSendType(sendType);  // 动态设置类型
                list.add(staff);
            }
        }
    }

    private void buildMessageQueue(wBlShipHdVO vo, wBlShipHd hd,
                                   CWeiXinConfigQy config, dArcStaff staff, CWeiXinConfigQy operationRobot) {
        StringBuilder title = new StringBuilder()
                .append(hd.getRecStore()).append("-").append("提报的物流残次").append("--").append(vo.getItemName());

        // 构建带参数的URL
        String messageUrl = new StringBuilder("https://mms.mumuso.com:8214/index/#/procurement/?")
                .append("billId=").append(vo.getBillId())
                .append("&staffId=").append(staff.getStaffId())
                .toString();
        StringBuilder sb = new StringBuilder().append(vo.getRemark()).append("——").append("门店已经确认,待区域经理点击链接进行审核操作!");

        // 直接创建对象并设置属性

        dingTalkMessageQueue queue = new dingTalkMessageQueue();
        queue.setMsgType("LINK");
        queue.setTitle(title.toString());
        queue.setText(sb.toString());
        if ("operate".equals(staff.getSendType())) {
            queue.setRobotToken(operationRobot.getAccessToken());
            queue.setRobotCode(operationRobot.getAeskey());
        } else {
            queue.setRobotToken(config.getAccessToken());
            queue.setRobotCode(config.getAeskey());
        }
        queue.setMessageUrl(messageUrl);
        queue.setPicUrl(defectiveJpg);
        queue.setUserIds(staff.getOldStaffId());
        sendDingTalkMessage(queue);

    }

    private void sendDingTalkMessage(dingTalkMessageQueue queue) {
        int result = dingTalkMessageQueueService.sendDingTalkLlnkMessage(queue);
        if (result <= 0) throw new BusinessException("消息发送失败");
    }

}
